package com.xzjt.web.aspect;

import cn.hutool.json.JSONUtil;
import com.xzjt.common.utils.DateUtils;
import com.xzjt.common.utils.HttpRequestUtils;
import com.xzjt.common.utils.StringUtils;

import com.xzjt.web.annotation.ParamsVerify;
import com.xzjt.web.exception.ParamsException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @User: yuandong
 * @Date: 2021/09/28 15:10
 * @Description: 请求参数切面配置，如果客户端请求的参数异常，则直接抛出异常，由全局异常处理程序处理
 */
@Component
@Aspect
@Slf4j
public class ParamsAspect {

    @Pointcut("@annotation(com.xzjt.web.annotation.ParamsVerify)")
    public void annotationPointCut() {

    }

    @Before("annotationPointCut()")
    public void paramsAop(JoinPoint joinPoint) throws ParamsException {
        MethodSignature sign = (MethodSignature) joinPoint.getSignature();
        Method method = sign.getMethod();
        ParamsVerify annotation = method.getAnnotation(ParamsVerify.class);
        String value = annotation.value();
        if (StringUtils.isNotEmpty(value)) {
            String[] paramArr = value.split(",");
            List<String> invalidParams = new ArrayList<>();
            for (String paramName : paramArr) {
                paramName = paramName.trim();
                String paramValue = HttpRequestUtils.getRequest().getParameter(paramName);
                if (StringUtils.isEmpty(paramValue)) {
                    invalidParams.add(paramName);
                }
            }
            if (!invalidParams.isEmpty()) {
                String time = DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
                String reqUri = HttpRequestUtils.getRequestUrl();   // 请求路径
                String reqParams = HttpRequestUtils.getRequestParams(); // 请求参数
                String targetClass = joinPoint.getTarget().toString();  // 请求目标class
                String methodName = joinPoint.getSignature().getName(); // 请求目标方法
                String line = time + " -> " + reqUri + " -> " + reqParams + " -> " + targetClass + " -> " + methodName;
                log.error(line + ">>>>>>>>>>>>>>>> 缺少必要的参数：" + JSONUtil.toJsonStr(invalidParams));
                throw new ParamsException(line + ">>>>>>>>>>>>>>>> 缺少必要的参数：" + JSONUtil.toJsonStr(invalidParams), JSONUtil.toJsonStr(invalidParams));
            }
        }
    }

}
